# clipboard_to_serial.py
import sys
import time

# 检查并导入必要的依赖
try:
    import pyperclip
except ImportError:
    print("错误: 未找到 pyperclip 模块")
    print("请运行: pip install pyperclip")
    sys.exit(1)

try:
    import serial
    import serial.tools.list_ports
except ImportError:
    print("错误: 未找到 pyserial 模块")
    print("请运行以下命令安装依赖:")
    print("  pip uninstall serial")
    print("  pip install pyserial")
    print("如果仍有问题，请运行:")
    print("  pip install -r requirements.txt")
    sys.exit(1)

# 验证 serial 模块是否正确导入
if not hasattr(serial, 'Serial'):
    print("错误: serial 模块版本不正确")
    print("请运行以下命令修复:")
    print("  pip uninstall serial")
    print("  pip uninstall pyserial") 
    print("  pip install pyserial")
    sys.exit(1)

def find_esp32_port():
    """自动检测ESP32设备的串口"""
    ports = serial.tools.list_ports.comports()
    esp32_port = None
    
    print("可用串口设备:")
    for port in ports:
        print(f"  {port.device}: {port.description}")
        # 检测ESP32相关的描述信息
        if any(keyword in port.description.lower() for keyword in ['usb', 'serial', 'ch340', 'cp210', 'ftdi']):
            if esp32_port is None:
                esp32_port = port.device
    
    if esp32_port:
        print(f"自动选择串口: {esp32_port}")
        return esp32_port
    else:
        print("未找到合适的串口设备")
        if ports:
            print(f"使用第一个可用端口: {ports[0].device}")
            return ports[0].device
        return None

# 配置ESP32的串口设备
port = find_esp32_port()

if not port:
    print("错误: 未找到可用的串口设备!")
    sys.exit(1)

try:
    ser = serial.Serial(port, 115200, timeout=1)
    print(f"成功连接到 {port}")
except Exception as e:
    print(f"连接串口失败: {e}")
    sys.exit(1)

prev_text = ""
print("剪贴板监控已启动，按 Ctrl+C 退出...")
print("复制任意文本到剪贴板，ESP32将自动显示")

try:
    while True:
        try:
            current_text = pyperclip.paste().strip()  # 获取剪贴板文本并去空格
            if current_text and current_text != prev_text:  # 仅在新内容时发送
                print(f"检测到新剪贴板内容: {current_text[:50]}{'...' if len(current_text) > 50 else ''}")
                
                # 首先发送清屏指令
                try:
                    print("发送清屏指令...")
                    ser.write("<CLEAR>\n".encode('utf-8'))
                    time.sleep(0.1)  # 等待ESP32处理清屏指令
                except Exception as e:
                    print(f"发送清屏指令失败: {e}")
                    continue
                
                # 然后发送新内容（分块发送以适应ESP32内存限制）
                chunks = [current_text[i:i+64] for i in range(0, len(current_text), 64)]
                print(f"发送 {len(chunks)} 个数据块...")
                
                for i, chunk in enumerate(chunks):
                    try:
                        ser.write(f"{chunk}\n".encode('utf-8'))  # 添加换行作为分隔符
                        time.sleep(0.05)  # 避免串口阻塞
                        print(f"  块 {i+1}/{len(chunks)} 已发送")
                    except Exception as e:
                        print(f"发送数据块失败: {e}")
                        break
                
                # 发送结束标记
                try:
                    ser.write("<END>\n".encode('utf-8'))
                    print("发送结束标记...")
                except Exception as e:
                    print(f"发送结束标记失败: {e}")
                
                prev_text = current_text
                print("发送完成!")
                
        except Exception as e:
            print(f"读取剪贴板失败: {e}")
            
        time.sleep(0.5)  # 降低CPU占用
        
except KeyboardInterrupt:
    print("\n正在退出...")
    
finally:
    if 'ser' in locals() and ser.is_open:
        ser.close()
        print("串口连接已关闭")